package com.shuai.user.controller;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shuai.common.constant.AuthenticationConstant;
import com.shuai.common.constant.ErrorCode;
import com.shuai.common.constant.InterfaceConstant;
import com.shuai.common.exception.BusinessException;
import com.shuai.common.rps.BaseResponse;
import com.shuai.common.utils.MyJWTUtil;
import com.shuai.common.utils.ResultUtils;
import com.shuai.user.domain.entity.InterfaceInfo;
import com.shuai.user.domain.entity.InterfaceParams;
import com.shuai.user.domain.request.InterfaceInfoQueryRequest;
import com.shuai.user.domain.request.InterfaceInfoSaveRequest;
import com.shuai.user.domain.request.InterfaceInfoUpdateRequest;
import com.shuai.user.domain.request.OnOrOffLineInterfaceRequest;
import com.shuai.user.domain.vo.InterfaceInfoRankVO;
import com.shuai.user.domain.vo.InterfaceInfoVO;
import com.shuai.user.service.InterfaceInfoService;
import com.shuai.user.service.InterfaceParamsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/interface_info")
@Slf4j
public class InterfaceInfoController {
    @Autowired
    private InterfaceInfoService interfaceInfoService;


    @Autowired
    private InterfaceParamsService interfaceParamsService;


    @PostMapping("/save")
    public BaseResponse<InterfaceInfoVO> save(@RequestBody InterfaceInfoSaveRequest interfaceInfoSaveRequest,
                                              @RequestHeader(AuthenticationConstant.AUTHENTICATION_HEADER) String authentication) {
        InterfaceInfo interfaceInfo = interfaceInfoService.saveItr(interfaceInfoSaveRequest, authentication);
        InterfaceInfoVO interfaceInfoVO = new InterfaceInfoVO();
        BeanUtils.copyProperties(interfaceInfo, interfaceInfoVO);
        return ResultUtils.success(interfaceInfoVO);
    }


    @GetMapping("/list_all")
    public BaseResponse<List<InterfaceInfoVO>> listAll(@RequestHeader(AuthenticationConstant.AUTHENTICATION_HEADER) String authentication, HttpServletRequest request) {
        return ResultUtils.success(interfaceInfoService.listAll(authentication));
    }


    @PostMapping("/update")
    public BaseResponse<Boolean> update(@RequestBody InterfaceInfoUpdateRequest updateRequest) {
        InterfaceInfo InterfaceInfo = new InterfaceInfo();
        BeanUtils.copyProperties(updateRequest, InterfaceInfo);
        return ResultUtils.success(interfaceInfoService.updateById(InterfaceInfo));
    }

    @DeleteMapping("/delete")
    public BaseResponse<Boolean> delete(Long id) {
        return ResultUtils.success(interfaceInfoService.removeById(id));
    }

    /**
     * 条件页查询
     */
    @RequestMapping(value = "/limit", method = RequestMethod.GET)
    public BaseResponse<Page<InterfaceInfo>> limit(InterfaceInfoQueryRequest queryRequest, HttpServletRequest request) {
        String apiName = queryRequest.getApiName();
        String method = queryRequest.getMethod();
        Integer apiStatus = queryRequest.getApiStatus();
        LambdaQueryWrapper<InterfaceInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(apiName), InterfaceInfo::getApiName, apiName);
        queryWrapper.eq(StringUtils.isNotBlank(method), InterfaceInfo::getMethod, method);
        queryWrapper.eq(apiStatus != null, InterfaceInfo::getApiStatus, apiStatus);
        Long pageSize = queryRequest.getPageSize();
        Long current = queryRequest.getCurrent();
        Page<InterfaceInfo> page = new Page<>(current, pageSize);
        page = interfaceInfoService.page(page, queryWrapper);
        return ResultUtils.success(page);
    }


    /**
     * 更新接口状态唯为已发布，仅管理员有权限操作
     */
    @PostMapping("online")
    public BaseResponse<Boolean> onLineInterface(OnOrOffLineInterfaceRequest onOrOffLineInterfaceRequest) {
        InterfaceInfo interfaceInfo = new InterfaceInfo();
        interfaceInfo.setId(onOrOffLineInterfaceRequest.getId());
        interfaceInfo.setApiStatus(1);
        return ResultUtils.success(interfaceInfoService.updateById(interfaceInfo));
    }


    /**
     * 下线接口，仅管理员有权限操作
     */
    @PostMapping("offline")
    public BaseResponse<Boolean> offLineInterface(OnOrOffLineInterfaceRequest onOrOffLineInterfaceRequest, HttpServletRequest request) {
        InterfaceInfo interfaceInfo = new InterfaceInfo();
        interfaceInfo.setId(onOrOffLineInterfaceRequest.getId());
        interfaceInfo.setApiStatus(0);
        return ResultUtils.success(interfaceInfoService.updateById(interfaceInfo));
    }


    @GetMapping("/getone")
    public BaseResponse<InterfaceInfoVO> getOne(OnOrOffLineInterfaceRequest request) {
        InterfaceInfo byId = interfaceInfoService.getById(request.getId());
        InterfaceInfoVO interfaceInfoVO = new InterfaceInfoVO();
        BeanUtils.copyProperties(byId, interfaceInfoVO);
        return ResultUtils.success(interfaceInfoVO);
    }


    /**
     * 新增接口信息
     */
    @PostMapping("/add_itr")
//    @AuthorityCheck(mustRole = UserConstant.USER_ROLE_ADMIN)
    public BaseResponse<Boolean> addInterfaceInfo(@RequestBody Map<String, String> params,
                                                  @RequestHeader(AuthenticationConstant.AUTHENTICATION_HEADER) String authentication) {
        Object payLoadItem = MyJWTUtil.getPayLoadItem(authentication, AuthenticationConstant.PAYLOAD_USERID);
        if (payLoadItem == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户身份信息异常");
        }
        Long userId = Long.valueOf(payLoadItem.toString());
        String paramString = params.get("paramString");
        if (StringUtils.isBlank(paramString)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数错误，新增接口失败");
        }
        InterfaceInfo interfaceInfo = JSONUtil.toBean(paramString, InterfaceInfo.class);
        interfaceInfo.setUserId(userId);

        Map<String, Object> paramsMap = JSONUtil.toBean(paramString, Map.class);

        // 接口的请求参数集合和响应参数集合
        // 将包含多条请求参数和响应参数的map转换为参数实体对象
        Map<String, Map<String, Object>> paramsEntityMap = this.toInterfaceInfoParamsEntitiesMap(paramsMap);
        List<InterfaceParams> interfaceParams = this.toInterfaceInfoParamsBean(paramsEntityMap);


        // 保存接口基本信息
        if (!interfaceInfoService.save(interfaceInfo)) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "接口基本信息保存失败");
        }

        // 填充参数实体中的接口ID信息
        for (InterfaceParams interfaceParam : interfaceParams) {
            interfaceParam.setInterfaceId(interfaceInfo.getId());
        }

        if (interfaceParams.size() == 0) {
            return ResultUtils.success(Boolean.TRUE);
        }

        // 保存接口参数信息
        if (!interfaceParamsService.saveBatch(interfaceParams)) {
            // 模拟事务回滚，删除已经保存的接口基本信息
            interfaceInfoService.removeById(interfaceInfo.getId());
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "接口参数信息保存失败");
        }
        return ResultUtils.success(Boolean.TRUE);
    }

    /**
     * 将参数map转为 InterfaceParams实体对象
     */
    private List<InterfaceParams> toInterfaceInfoParamsBean(Map<String, Map<String, Object>> paramsEntityMap) {
        List<InterfaceParams> interfaceParamsList = new ArrayList<>();
        for (String key : paramsEntityMap.keySet()) {
            Map<String, Object> paramsMap = paramsEntityMap.get(key);
            InterfaceParams interfaceParams = JSONUtil.toBean(JSONUtil.toJsonStr(paramsMap), InterfaceParams.class);
            if (key.startsWith("req_")) {
                interfaceParams.setParamOrder(InterfaceConstant.reqParam);
            } else if (key.startsWith("rps_")) {
                interfaceParams.setParamOrder(InterfaceConstant.rpsParam);
            }
            interfaceParamsList.add(interfaceParams);
        }
        return interfaceParamsList;
    }

    /**
     * 将包含多条数据的参数map集合转换为多条参数实体对象对应的map
     *
     * @return
     */
    private Map<String, Map<String, Object>> toInterfaceInfoParamsEntitiesMap(Map<String, Object> paramsMap) {
        Map<String, Map<String, Object>> paramEntityMap = new HashMap<>();
        // 先处理请求参数map
        for (String key : paramsMap.keySet()) {
            if (key.startsWith("req_") || key.startsWith("rps_")) {
                String suffix = key.substring(0, key.lastIndexOf("."));
                String param = key.substring(key.lastIndexOf(".") + 1);
                if (paramEntityMap.get(suffix) == null) {
                    paramEntityMap.put(suffix, new HashMap<>());
                }
                paramEntityMap.get(suffix).put(param, paramsMap.get(key));
            }
        }
        return paramEntityMap;
    }


    @GetMapping("/rank/{topN}")
    public BaseResponse<List<InterfaceInfoRankVO>> getTopNRank(@PathVariable("topN") Integer topN) {
        List<InterfaceInfoRankVO> res = interfaceInfoService.getInvokeRank(topN);
        return ResultUtils.success(res);
    }
}
